package com.sunxd.zstudy.juc;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author: LongAdder > Atomic > sync  在数量大，并发高的时候，如果并发小，sync反而最快
 * LongAdder 内部使用将线程分成几组，然后进行cas计算，最后求总和，所以快
 * @date: 2021-03-30 21:57
 **/
public class T08_AtomicVsSyncVsLongAdder {

    private AtomicLong count1 = new AtomicLong(0L);
    private Long count2 = 0L;
    private LongAdder count3 = new LongAdder();

    static void atomic(){
        T08_AtomicVsSyncVsLongAdder t08_atomicVsSyncVsLongAdder = new T08_AtomicVsSyncVsLongAdder();
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            threadList.add(new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    t08_atomicVsSyncVsLongAdder.count1.incrementAndGet();
                }
            }));
        }
        Long start = System.currentTimeMillis();
        System.out.println("开始 ： " + start);

        threadList.forEach(o -> {
            o.start();
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Long end = System.currentTimeMillis();
        System.out.println("结束 ： " + end);
        System.out.println("atomic  耗时  ： " + (end - start) + " 值="+t08_atomicVsSyncVsLongAdder.count1);
    }

    static void sync(){
        T08_AtomicVsSyncVsLongAdder t08_atomicVsSyncVsLongAdder = new T08_AtomicVsSyncVsLongAdder();
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            threadList.add(new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    synchronized (t08_atomicVsSyncVsLongAdder){
                        t08_atomicVsSyncVsLongAdder.count2++;
                    }
                }
            }));
        }
        Long start = System.currentTimeMillis();
        System.out.println("开始start ： " + start);

        threadList.forEach(o -> {
            o.start();
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Long end = System.currentTimeMillis();
        System.out.println("开始end ： " + end);
        System.out.println(" sync 耗时  ： " + (end - start) + " 值="+t08_atomicVsSyncVsLongAdder.count2);
    }

    static void longAdder(){
        T08_AtomicVsSyncVsLongAdder t08_atomicVsSyncVsLongAdder = new T08_AtomicVsSyncVsLongAdder();
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            threadList.add(new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    t08_atomicVsSyncVsLongAdder.count3.increment();
                }
            }));
        }
        Long start = System.currentTimeMillis();
        System.out.println("开始 ： " + start);

        threadList.forEach(o -> {
            o.start();
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Long end = System.currentTimeMillis();
        System.out.println("结束 ： " + end);
        System.out.println("longAdder  耗时  ： " + (end - start) + " 值="+t08_atomicVsSyncVsLongAdder.count3);
    }

    public static void main(String[] args) {
        atomic();
        sync();;
        longAdder();
    }

}
